// Copyright (c) 2007 Robin Boerdijk. All rights reserved.
//
// This software is licensed under the terms of the Microsoft Reciprocal License as described 
// in the file LICENSE.txt, which you should have received as part of this distribution. The 
// license terms are also available at http://www.opensource.org/licenses/ms-rl.html.

#ifndef wtk_Event_h_included
#define wtk_Event_h_included

#include <vector>

namespace wtk
{
	template<typename SenderType> class Event
	{
	private:

		class IHandler
		{
		public:

			virtual ~IHandler() { }

			virtual void Handle(SenderType *sender) = 0;
		};

		typedef std::vector<IHandler *> HandlerList;

		template<class HandlerClass> class Handler : public IHandler
		{
		public:

			typedef void (HandlerClass::*HandlerMethod)(SenderType *sender);

			Handler(HandlerClass *object, HandlerMethod method)
				: m_object(object)
				, m_method(method)
			{
			}

			virtual void Handle(SenderType *sender)
			{
				(m_object->*m_method)(sender);
			}

		private:

			HandlerClass *m_object;

			HandlerMethod m_method;
		};

	public:

		Event()
		{
		}

		~Event()
		{
			for (HandlerList::iterator it = m_handlers.begin(), end = m_handlers.end(); it != end; ++it) {
				delete *it;
			}
		}

		template<class HandlerClass> void AddHandler(HandlerClass *object, void (HandlerClass::*method)(SenderType *sender))
		{
			m_handlers.push_back(new Handler<HandlerClass>(object, method));
		}

	private:

		Event(const Event &other); // prevent copying

		Event &operator=(const Event &other); // prevent assignment

		HandlerList m_handlers;

		friend class Window;

		void Signal(SenderType *sender)
		{
			for (HandlerList::iterator it = m_handlers.begin(), end = m_handlers.end(); it != end; ++it) {
				(*it)->Handle(sender);
			}
		}
	};
}

#endif